package com.loong.web.suppert.collection.list;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import com.loong.web.suppert.collection.list.KvnList.Kvn;

/**
 * 键值名集合
 * 
 * @author 张成轩
 * @param <K> 键类型
 * @param <V> 值类型
 * @param <N> 名类型
 */
public class KvnList<K, V, N> implements List<Kvn<K, V, N>> {

	private Map<K, Kvn<K, V, N>> keys = new HashMap<K, Kvn<K, V, N>>();
	private Map<V, Kvn<K, V, N>> values = new HashMap<V, Kvn<K, V, N>>();
	private List<Kvn<K, V, N>> list = new LinkedList<Kvn<K, V, N>>();

	@Override
	public int size() {

		return list.size();
	}

	@Override
	public boolean isEmpty() {

		return list.isEmpty();
	}

	@Override
	public void clear() {

		keys.clear();
		values.clear();
		list.clear();
	}

	@Override
	@Deprecated
	public Kvn<K, V, N> set(int index, Kvn<K, V, N> element) {

		throw new RuntimeException("set method has bee deprecated");
	}

	@Override
	public Kvn<K, V, N> get(int index) {

		return list.get(index);
	}

	/**
	 * 通过键获取名
	 * 
	 * @param k 键
	 * @return 对象
	 */
	public Kvn<K, V, N> getKvnByK(K k) {

		return keys.get(k);
	}

	/**
	 * 通过值获取名
	 * 
	 * @param v 值
	 * @return 对象
	 */
	public Kvn<K, V, N> getKvnByV(V v) {

		return values.get(v);
	}

	/**
	 * 通过键获取名
	 * 
	 * @param k 键
	 * @return 名
	 */
	public N getNByK(K k) {

		Kvn<K, V, N> o = keys.get(k);
		return o == null ? null : o.getName();
	}

	/**
	 * 通过值获取名
	 * 
	 * @param v 值
	 * @return 名
	 */
	public N getNByV(V v) {

		Kvn<K, V, N> o = values.get(v);
		return o == null ? null : o.getName();
	}

	/**
	 * 通过键获取值
	 * 
	 * @param k 键
	 * @return 对象
	 */
	public V getV(K k) {

		Kvn<K, V, N> o = keys.get(k);
		return o == null ? null : o.getValue();
	}

	/**
	 * 通过值获取键
	 * 
	 * @param v 键
	 * @return 对象
	 */
	public K getK(V v) {

		Kvn<K, V, N> o = values.get(v);
		return o == null ? null : o.getKey();
	}

	/**
	 * 新增
	 * 
	 * @param k 键
	 * @param v 值
	 * @param n 名称
	 * @return 是否成功
	 */
	public boolean add(K k, V v, N n) {

		return add(new Kvn<K, V, N>(k, v, n));
	}

	@Override
	public boolean add(Kvn<K, V, N> e) {

		Kvn<K, V, N> k = keys.get(e.getKey());
		Kvn<K, V, N> v = values.get(e.getValue());
		if (k != null || v != null)
			return false;
		list.add(e);
		keys.put(e.getKey(), e);
		values.put(e.getValue(), e);
		return true;
	}

	@Override
	public void add(int index, Kvn<K, V, N> e) {

		Kvn<K, V, N> k = keys.get(e.getKey());
		Kvn<K, V, N> v = values.get(e.getValue());
		if (k != null || v != null)
			return;
		list.add(index, e);
		keys.put(e.getKey(), e);
		values.put(e.getValue(), e);
	}

	@Override
	public boolean addAll(Collection<? extends Kvn<K, V, N>> c) {

		return addAll(list.size(), c);
	}

	@Override
	public boolean addAll(int index, Collection<? extends Kvn<K, V, N>> c) {

		for (Kvn<K, V, N> o : c)
			if (list.contains(o))
				return false;
		for (Kvn<K, V, N> o : c)
			add(index++, o);
		return true;
	}

	@Override
	public List<Kvn<K, V, N>> subList(int fromIndex, int toIndex) {

		return list.subList(fromIndex, toIndex);
	}

	@Override
	public int indexOf(Object o) {

		return list.indexOf(o);
	}

	@Override
	public int lastIndexOf(Object o) {

		return list.lastIndexOf(o);
	}

	@Override
	@SuppressWarnings("rawtypes")
	public boolean remove(Object o) {

		if (!(o instanceof Kvn))
			return false;
		boolean succ = list.remove(o);
		if (succ) {
			keys.remove(((Kvn) o).getKey());
			values.remove(((Kvn) o).getValue());
		}
		return succ;
	}

	@Override
	public Kvn<K, V, N> remove(int index) {

		Kvn<K, V, N> o = list.get(index);
		list.remove(index);
		keys.remove(o.getKey());
		values.remove(o.getValue());
		return o;
	}

	@Override
	public boolean removeAll(Collection<?> c) {

		boolean exists = containsAll(c);
		if (exists)
			for (Object o : c)
				remove(o);
		return exists;
	}

	@Override
	public boolean contains(Object o) {

		return list.contains(o);
	}

	@Override
	public boolean containsAll(Collection<?> c) {

		for (Object o : c)
			if (!list.contains(o))
				return false;
		return true;
	}

	@Override
	@Deprecated
	public boolean retainAll(Collection<?> c) {

		throw new RuntimeException("set method has bee deprecated");
	}

	@Override
	public Iterator<Kvn<K, V, N>> iterator() {

		return list.iterator();
	}

	@Override
	public ListIterator<Kvn<K, V, N>> listIterator() {

		return list.listIterator();
	}

	@Override
	public ListIterator<Kvn<K, V, N>> listIterator(int index) {

		return list.listIterator(index);
	}

	@Override
	public Object[] toArray() {

		return list.toArray();
	}

	@Override
	public <T> T[] toArray(T[] a) {

		return list.toArray(a);
	}

	/**
	 * 键值名对象
	 * 
	 * @author 张成轩
	 * @param <K> 键类型
	 * @param <V> 值类型
	 * @param <N> 名称类型
	 */
	public static class Kvn<K, V, N> {

		private K key;
		private V value;
		private N name;

		/**
		 * 构造方法
		 * 
		 * @param key 键
		 * @param value 值
		 * @param name 名称
		 */
		public Kvn(K key, V value, N name) {

			this.key = key;
			this.value = value;
			this.name = name;
		}

		/**
		 * @return 键
		 */
		public K getKey() {

			return key;
		}

		/**
		 * @return 值
		 */
		public V getValue() {

			return value;
		}

		/**
		 * @return 名称
		 */
		public N getName() {

			return name;
		}
	}
}
